<?php
defined('BASEPATH') or exit('No direct script access allowed');

/**
 * 基本model方法
 */
class TP_Model extends CI_Model
{
    protected $table;
    private $defaltSysCreator = '0';
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * @Desc     SQL查询【全】,请使用sql_format进行组装
     * @Author   pekey
     * @DateTime 2020-05-11T18:52:20+0800
     * @param    [sql]sql语句；
     * @return   [array]返回二维数组集合
     */
    public function query($sql)
    {
        log_info($sql);
        return $this->db->query($sql)->result_array();
    }

    /**
     * @Desc     SQL单条查询【全】，请使用sql_format进行组装
     * @Author   pekey
     * @DateTime 2020-05-11T18:53:01+0800
     * @param    [sql]sql语句
     * @return   [array]一维数组，或空null
     */
    public function single($sql)
    {
        log_info($sql);
        $query = $this->db->query($sql);
        $row = $query->first_row();
        if (isset($row)) {
            return $row;
        }
        return null;
    }

    /**
     * @Desc     insert、update语句操作【全】，请使用sql_format进行组装
     * @Author   pekey
     * @DateTime 2020-05-11T18:53:54+0800
     * @param    [sql]，自定义sql语句
     */
    public function execute($sql)
    {
        $this->db->query($sql);
        log_info($this->db->last_query());
    }

    /**
     * @Desc     快速查询单数据方法【全】
     * @Author   pekey
     * @DateTime 2020-05-11T18:54:39+0800
     * @param    [connar]多维数组，用于拼接。具体可查看chekparams方法
     * @return   [array]数组
     */
    public function get_single_full($conarr)
    {
        //参数集成
        $this->checkParams($conarr);
        $conarr['cond'][$this->table . '.is_delete'] = DeleteState::UnDelete[TPEnum::Value];
        $v = $this->db->get()->row_array();
        log_info($this->db->last_query());
        return $v;
    }

    /**
     * @Desc     快速查询单数据方法【简易】
     * @Author   pekey
     * @DateTime 2020-05-11T18:56:01+0800
     * @param    [cond]一维数组，用于where条件
     * @return   [array]返回结果一条数据，一维数组
     */
    public function get_single($cond)
    {
        $conarr['cond'] = $cond;
        $conarr['cond'][$this->table . '.is_delete'] = DeleteState::UnDelete[TPEnum::Value];
        //参数集成
        $this->checkParams($conarr);
        $v = $this->db->get()->row_array();
        log_info($this->db->last_query());
        return $v;
    }

    /**
     * @Desc     数据插入，可判断单数据或多数据
     * @Author   pekey
     * @DateTime 2020-05-11T18:58:01+0800
     * @param    [datas]一维数组或多维数组
     * @return   [int]返回的自增长id
     */
    public function add($datas)
    {
        if (count($datas) == count($datas, 1)) {
            $datas['creator'] = isset($_SESSION[SESS_UUID]) ? $_SESSION[SESS_UUID] : $this->defaltSysCreator;
            //表示一维数组
            $this->db->insert($this->table, $datas);
            log_info($this->db->last_query());
            return $this->db->insert_id();
        } else {
            // foreach ($datas as $key => $data) {
            //     $datas[$key]['creator'] = isset($_SESSION[SESS_UUID]) ? $_SESSION[SESS_UUID] : $this->defaltSysCreator;
            // }
            $this->db->insert_batch($this->table, $datas);
            log_info($this->db->last_query());
        }

    }

    /**
     * 根据多重条件查找修改数据
     */
    /**
     * @Desc     多条件修改
     * @Author   pekey
     * @DateTime 2020-05-11T19:02:05+0800
     * @param    [data] 需要改变的字段和结果
     * @param    [cond] 可多条件查询
     */
    public function update($data, $cond = array())
    {
        $data['updator'] = isset($_SESSION[SESS_UUID]) ? $_SESSION[SESS_UUID] : $this->defaltSysCreator;
        if (count($cond) > 0) {
            $this->db->where($cond);
        }
        //  加入主条件，查询非删除数据
        $this->db->where($this->table . ".is_delete = " . DeleteState::UnDelete[TPEnum::Value]);
        $this->db->update($this->table, $data);
        log_info($this->db->last_query());
    }

    /**
     * @Desc     复杂条件修改，如根据不同的变量修改成不同的值
     * @Author   pekey
     * @DateTime 2020-05-11T19:02:56+0800
     * @param    [data]更改的条件及结果
     * @param    [title]变量值
     * 例子：
     * $data = array(
     *    array(
     *       'title' => 'My title' ,
     *       'name' => 'My Name 2' ,
     *        'date' => 'My date 2'
     *    ),
     *    array(
     *       'title' => 'Another title' ,
     *       'name' => 'Another Name 2' ,
     *        'date' => 'Another date 2'
     *     )
     * );

     * $this->db->update_batch('mytable', $data, 'title');

     *  Produces:
     *  UPDATE `mytable` SET `name` = CASE
     *  WHEN `title` = 'My title' THEN 'My Name 2'
     *  WHEN `title` = 'Another title' THEN 'Another Name 2'
     *  ELSE `name` END,
     *  `date` = CASE
     *  WHEN `title` = 'My title' THEN 'My date 2'
     *  WHEN `title` = 'Another title' THEN 'Another date 2'
     *  ELSE `date` END
     *  WHERE `title` IN ('My title','Another title')
     */
    public function update_bat($data, $title)
    {
        foreach ($data as $d) {
            $d['updator'] = isset($_SESSION[SESS_UUID]) ? $_SESSION[SESS_UUID] : $this->defaltSysCreator;
        }
        $this->db->update_batch($this->table, $data, $title);
        log_info($this->db->last_query());
    }

    /**
     * [delete 逻辑删除]
     * @Description 逻辑删除，批量删除，删除不可逆，故状态写死。
     * @Author      FengPQ
     * @DateTime    2020-05-24T16:52:20+0800
     * @param       [type]                   $cond [description]
     * @return      [type]                         [description]
     */
    public function delete($cond,$is_delete = false)
    {
        if (count($cond) > 0) {
            $this->db->where($cond);
        }
        if($is_delete==false){
            $this->db->update($this->table, array("is_delete" => DeleteState::Delete[TPEnum::Value]));
        }else{
             $this->db->delete($this->table,$cond);
        }

       
        log_info($this->db->last_query());
    }
    /**
     * [delete_full 多条件逻辑删除]
     * @Description 多条件逻辑删除
     * @Author      FengPQ
     * @DateTime    2020-05-24T17:13:21+0800
     * @param       [type]                   $connar [description]
     * @return      [type]                           [description]
     */
    public function delete_full($conarr)
    {
        $this->checkParams($conarr);
        $this->db->update($this->table, array("is_delete" => DeleteState::Delete[TPEnum::Value]));
        log_info($this->db->last_query());
    }

    /**
     * @Desc     简易版批量获取数据
     * @Author   pekey
     * @DateTime 2020-05-11T19:15:51+0800
     * @param    [type]
     * @param    string
     * @param    string
     * @return   [type]
     */
    public function get_list($cond, $orderby = 'id asc', $where = '')
    {
        $conarr = array();
        $conarr['cond'] = $cond;
        $conarr['orderby'] = $orderby;
        if ($where != "") {
            $conarr['where'] = $where;
        }

        return $this->get_list_full($conarr);
    }

    /**
     * 根据条件查询列表信息
     * where 可以用array，可以用 长字符串，可以用array 中加入>,like 等
     * spec_where 可以用于特殊语句的where
     */
    public function get_list_full($conarr = array())
    {
        $conarr = $this->checkParams($conarr);
        $datas = $this->db->get()->result_array();
        log_info($this->db->last_query());
        return $datas;
    }

    /**
     * [get_count description]
     * @Description 用于计算count数量
     * @Author      FengPQ
     * @DateTime    2020-05-14T08:16:18+0800
     * @param       array                    $cond [建议数组条件，key-value]
     * @return      [type]                         [数量]
     */
    public function get_count($cond = array())
    {
        $conarr = array();
        $conarr['cond'] = $cond;
        $num = $this->get_count_full($conarr);
        return $num;
    }

    /**
     * [get_count_full 根据条件查询count]
     * @Description 方法描述
     * @Author      FengPQ
     * @DateTime    2020-05-14T08:17:41+0800
     * @param       array                    $conarr [conarr 可以用array，可以用 长字符串，可以用array 中加入>,like 等]
     * @return      [type]                           [description]
     */
    public function get_count_full($conarr = array())
    {
        $conarr['items'] = "count(*) as num";
        $conarr['isCount'] = true;
        $this->checkParams($conarr);
        $num = $this->db->get()->first_row()->num;
        log_info($this->db->last_query());
        return $num;
    }

    /**
     * [get_page_list 获取分页list,默认pagesize=10]
     * @Description 方法描述
     * @Author      FengPQ
     * @DateTime    2020-05-14T08:18:17+0800
     * @param       array                    $conarr [条件数组]
     * @return      [type]                           [自定义数组，包含totalpage，pageNo，ret]
     */
    public function get_page_list($conarr = array())
    {
        //总数量
        $data["count"] = intval($this->get_count_full($conarr));

        $conarr = $this->checkParams($conarr);
        //总页数
        $data["totalPage"] = ceil($data["count"] / $conarr['pageSize']);
        $data['pageNo'] = $conarr['pageNo'];
        $data["ret"] = $this->db->get()->result_array();
        log_info($this->db->last_query());
        return $data;
    }

    /**
     * @Desc     主核心，用于对参数进行判断
     * @Author   pekey
     * @DateTime 2020-05-12T19:21:49+0800
     * @param    array 数组参数
     * @return   [type]
     */
    private function checkParams($conarr = array())
    {

        //items - 查询项 - "id,name,num..."
        if (isset($conarr['items'])) {
            $this->db->select($conarr['items']);
        } else {
            $this->db->select("*");
        }

        //groupby - 分组项 - "id"
        if (isset($conarr['groupby'])) {
            $this->db->group_by($conarr['groupby']);
        }

        //table名,非自定义参数
        $this->db->from($this->table);

        //join - 连接 array('tablename','a.id=b.id','left、right、innner')，默认left
        if (!empty($conarr['join'])) {
            if (count($conarr['join']) == count($conarr['join'], 1)) {
                //一维数组
                if (!isset($conarr['join'][2])) {
                    $conarr['join'][2] = "left";
                }
                $conarr['join'][1] .= " and " . $conarr['join'][0] . ".is_delete = " . DeleteState::UnDelete[TPEnum::Value];
                $this->db->join($conarr['join'][0], $conarr['join'][1], $conarr['join'][2]);
            } else {
                //多维数组
                foreach ($conarr['join'] as $j) {
                    if (!isset($j[2])) {
                        $j[2] = "left";
                    }
                    $j[1] .= " and " . $j[0] . ".is_delete = " . DeleteState::UnDelete[TPEnum::Value];
                    $this->db->join($j[0], $j[1], $j[2]);
                }
            }
        }

        //  加入主条件，查询非删除数据
        $this->db->where($this->table . ".is_delete = " . DeleteState::UnDelete[TPEnum::Value]);

        //普通条件，key-value方式
        if (isset($conarr['cond'])) {
            $this->db->where($conarr['cond']);
        }

        //like語句array(字段，值，百分号位置)，第三个参数可以是before，after，both，默认both
        if (isset($conarr['like'])) {
            foreach ($conarr['like'] as $key => $v) {
                if (!isset($v[1])) {
                    $v[1] = 'both';
                }
                $this->db->like($key, $v[0], $v[1]);
            }
        }

        //特殊where条件，自定义输入
        if (isset($conarr['where'])) {
            $this->db->where($conarr['where']);
        }

        //in语句，$conarr['in'] = array('id',$ar);
        if (isset($conarr['in'])) {
            $this->db->where($conarr['in'][0] . ' in (' . array_sql_in($conarr['in'][1]) . ')');
        }

        //如果不是计数，则进行排序和分页
        if (!isset($conarr['isCount'])) {
            //排序
            if (isset($conarr['orderby'])) {
                $this->db->order_by($conarr['orderby']);
            }

            //分页
            if (isset($conarr['pageNo'])) {
                $this->db->limit($conarr['pageSize'], $conarr['pageSize'] * ($conarr['pageNo'] - 1));
            }
        }

        return $conarr;
    }

    /**
     * [pickAllParams ]
     * @Description 简易版挑选所有参数，将所有参数放到connar里面，模糊搜索的对象特殊处理
     * @Author      FengPQ
     * @DateTime    2020-05-14T08:22:28+0800
     * @param       [type]                   $params [参数对象]
     * @return      [type]                           [数组对象]
     */
    public function pickAllParams($params)
    {
        $connar = array();
        foreach ($params as $key => $value) {
            if ($key == "pageNo") {
                $connar['pageNo'] = $value;
                continue;
            } else if ($key == "pageSize") {
                $connar['pageSize'] = $value;
                continue;
            }

            if (strstr($key, '_')) {
                $connar['like'][substr($key, 1)] = $value;
            } else {
                $connar['cond'][$key] = $value;
            }
        }
        return $connar;
    }

    /**
     * [pickParam description]
     * @Description 单条件进行分类
     * @Author      FengPQ
     * @DateTime    2020-05-14T08:24:53+0800
     * @param       [type]                   $conarr [数组]
     * @param       [type]                   $params [前端参数]
     * @param       [type]                   $key    [前端参数字段]
     * @param       string                   $item   [表对应字段]
     * @param       boolean                  $isLike [是否模糊搜索]
     * @return      [type]                           [数组对象]
     */
    public function pickParam($conarr, $params, $key, $item = "", $isLike = true)
    {
        if ($item == "") {
            $item = $key;
        }
        if (!isset($params[$item])) {
            return $conarr;
        }
        if ($isLike) {
            $conarr['like'][$key] = array($params[$item]);
        } else {
            $conarr['cond'][$key] = $params[$item];
        }

        return $conarr;
    }

    /**
     * [pickPages 获取分页数据]
     * @Description 获取分页数据
     * @Author      FengPQ
     * @DateTime    2020-05-14T08:26:31+0800
     * @param       [type]                   $conarr [条件数组]
     * @param       [type]                   $params [前端参数]
     * @return      [type]                           [条件数组]
     */
    public function pickPages($conarr, $params)
    {
        $conarr['pageNo'] = $params['pageNo'];
        $conarr['pageSize'] = $params['pageSize'];
        return $conarr;
    }

}
